package com.heihei.serviceimpl.res;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.heihei.common.page.Condition;
import com.heihei.common.page.Query;
import com.heihei.common.response.ResponseVO;
import com.heihei.entity.res.ResResourceEntity;
import com.heihei.entity.res.ResResourceTagEntity;
import com.heihei.entity.res.ResTagEntity;
import com.heihei.enums.DeleteFlagEnum;
import com.heihei.mapper.res.ResResourceMapper;
import com.heihei.service.res.ResResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heihei.service.res.ResResourceTagService;
import com.heihei.service.res.ResTagService;
import com.heihei.utils.dto.BeanUtil;
import com.heihei.vo.res.ResResourceIdAndTagVO;
import com.heihei.vo.res.ResResourceQueryParamVO;
import com.heihei.vo.res.ResResourceVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author duanhengfei
 * @since 2021-11-23
 */
@Service
public class ResResourceServiceImpl extends ServiceImpl<ResResourceMapper, ResResourceEntity> implements ResResourceService {

    /** 资源-标签 中间表 */
    @Resource
    private ResResourceTagService resResourceTagService;

    /** 标签表 */
    @Resource
    private ResTagService resTagService;

    /**
     * 添加
     *
     * @author duanhf
     * 2021年12月07日 14:45:53
     */
    @Transactional
    @Override
    public ResponseVO<String> add(ResResourceVO paramVo) {
        paramVo.setId(null);
        //资源名称不能为空
        if(StringUtils.isEmpty(paramVo.getResName())) {
            return ResponseVO.paramLess("资源名称不能为空");
        }

        //先添加资源信息
        ResResourceEntity resEntity = BeanUtil.copy(paramVo, ResResourceEntity.class);
        this.save(resEntity);

        if(CollectionUtils.isNotEmpty(paramVo.getTagList())) {
            //再选择性添加标签信息，返回的tagList是所有的标签id
            List<String> tagIdList = this.resTagService.addSelective(paramVo.getTagList());

            //添加中间表信息之前，保险起见，清除一下该资源关联的标签id
            this.resResourceTagService.deleteByResourceId(resEntity.getId());

            //添加中间表信息
            List<ResResourceTagEntity> collect = this.buildAddResTagList(resEntity.getId(), tagIdList);
            this.resResourceTagService.saveBatch(collect);
        }

        //返回结果
        return ResponseVO.dealSuccess(resEntity.getId());
    }

    /**
     * 修改
     *
     * @author duanhf
     * 2021年12月08日 16:00:44
     */
    @Override
    @Transactional
    public ResponseVO<Boolean> myUpdateById(ResResourceVO paramVo) {
        //修改时，主键ID不能为空
        if(StringUtils.isEmpty(paramVo.getId())) {
            return ResponseVO.paramLess("请传入要修改的主键ID");
        }
        //不能修改已删除的记录
        ResResourceEntity currExistEntity = this.getById(paramVo.getId());
        if(currExistEntity == null || DeleteFlagEnum.DELETED.getKey().equals(currExistEntity.getDelFlag())) {
            return ResponseVO.paramIllegal("该记录不存在或已被删除");
        }
        //先修改资源
        ResResourceEntity resEntity = BeanUtil.copy(paramVo, ResResourceEntity.class);
        this.updateById(resEntity);

        //清除掉原本的中间表信息
        this.resResourceTagService.deleteByResourceId(resEntity.getId());

        if(CollectionUtils.isNotEmpty(paramVo.getTagList())) {
            //选择性添加标签信息，返回的tagList是所有的标签id
            List<String> tagIdList = this.resTagService.addSelective(paramVo.getTagList());
            //添加中间表信息
            List<ResResourceTagEntity> collect = this.buildAddResTagList(resEntity.getId(), tagIdList);
            this.resResourceTagService.saveBatch(collect);
        }

        return ResponseVO.dealSuccess(true);
    }

    /**
     * 构建用于添加的 资源-标签中间表List
     *
     * @author duanhf
     * 2021年12月08日 16:09:09
     */
    public List<ResResourceTagEntity> buildAddResTagList(String resourceId, List<String> tagIdList) {
        List<ResResourceTagEntity> collect = tagIdList.stream().map(tagId -> {
            ResResourceTagEntity resTagEnt = new ResResourceTagEntity();
            resTagEnt.setResourceId(resourceId);
            resTagEnt.setTagId(tagId);
            return resTagEnt;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 删除
     *
     * @author duanhf
     * 2021年12月08日 16:11:09
     */
    @Override
    public ResponseVO<Boolean> deleteByIdLogic(String id) {
        ResResourceEntity entity = new ResResourceEntity();
        entity.setId(id);
        entity.setDelFlag(DeleteFlagEnum.DELETED.getKey());
        boolean flag = this.updateById(entity);
        if(!flag) {
            return ResponseVO.dealSuccess(false, "该记录可能不存在或已被删除");
        }
        return ResponseVO.dealSuccess(true);
    }

    /**
     * 批量删除
     *
     * @author duanhf
     * 2021年12月08日 16:34:17
     */
    @Override
    public ResponseVO<Boolean> deleteBatch(List<String> idList) {
        if(CollectionUtils.isEmpty(idList)) {
            return ResponseVO.paramLess("请传入要删除的ID数组");
        }
        List<ResResourceEntity> collect = idList.stream().map(id -> {
            ResResourceEntity entity = new ResResourceEntity();
            entity.setId(id);
            entity.setDelFlag(DeleteFlagEnum.DELETED.getKey());
            return entity;
        }).collect(Collectors.toList());
        boolean flag = this.updateBatchById(collect);
        if(!flag) {
            return ResponseVO.dealSuccess(false, "选中的记录可能不存在或已被删除");
        }
        return ResponseVO.dealSuccess(true);
    }

    /**
     * 列表查询
     *
     * @author duanhf
     * 2021年12月08日 16:44:43
     */
    @Override
    public ResponseVO<IPage<ResResourceVO>> myPageList(ResResourceQueryParamVO paramVo, Query query) {
        IPage<ResResourceVO> pageList = this.baseMapper.pageConditional(Condition.getPage(query), paramVo, DeleteFlagEnum.NOT_DELETED.getKey());
        //获取当前页的资源idList
        List<String> currPageResIdList = pageList.getRecords().stream().map(ResResourceVO::getId).collect(Collectors.toList());
        //根据当前页的idList，查询这些id关联的所有标签
        List<ResResourceIdAndTagVO> resIdAndTagList = this.resResourceTagService.selectTagWithResIdList(currPageResIdList, DeleteFlagEnum.NOT_DELETED.getKey());
        if(CollectionUtils.isNotEmpty(resIdAndTagList)) {
            //构建Map
            Map<String, List<ResTagEntity>> resIdAndTagMap = new HashMap<>();
            for (ResResourceIdAndTagVO resEntity : resIdAndTagList) {
                resIdAndTagMap.put(resEntity.getResourceId(), resEntity.getTagList());
            }
            //填充标签数据
            for (ResResourceVO record : pageList.getRecords()) {
                String currId = record.getId();
                if(resIdAndTagMap.containsKey(currId)) {
                    record.setTagList(resIdAndTagMap.get(currId));
                }
            }
        }
        //返回结果
        return ResponseVO.dealSuccess(pageList);
    }

    /**
     * 详情
     *
     * @author duanhf
     * 2021年12月09日 10:32:17
     */
    @Override
    public ResponseVO<ResResourceVO> myGetById(String id) {
        ResResourceVO vo = this.baseMapper.getByIdDetail(id, DeleteFlagEnum.NOT_DELETED.getKey());
        if(vo == null) {
            return ResponseVO.paramLess("该记录不存在或已被删除");
        }
        return ResponseVO.dealSuccess(vo);
    }
}
